package cate.game.activity.treasure;

import cate.common.table.activity.treasure.row.TreasureBaseRow;
import cate.common.table.activity.treasure.row.TreasureCallPoolRow;
import cate.common.table.activity.treasure.row.TreasureCallRow;
import cate.common.table.activity.treasure.row.TreasureOutputRow;
import cate.common.table.d.GDOperation;
import cate.common.util.GameResult;
import cate.common.util.XT;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.treasure.data.TreasureCallExchange;
import cate.game.activity.treasure.msg.TreasureDrawResp;
import cate.game.activity.treasure.msg.TreasureInfoResp;
import cate.game.chat.ChatContentParam;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class TreasureActivity extends RoleActivitySingle {
    @NoteField("累计抽奖次数")
    public int historyDrawTimes;

    @NoteField("剩余免费次数")
    public int freeTimes;

    @NoteField("钻石抽奖次数")
    public int diaTimes;

    @NoteField("兑换")
    public TreasureCallExchange exchange;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (exchange == null) {
            exchange = new TreasureCallExchange();
        }
        exchange.initialize(this);
    }

    @Override
    public void onEnter() {
        super.onEnter();
        exchange.onEnter();
    }

    @Override
    public void onRoleOpen() {
        exchange.onStart();
    }

    @Override
    public void onRoleEnd() {
        clear();
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        TreasureBaseRow baseRow = showBaseRow(historyDrawTimes + 1);
        if (baseRow == null || !enable()) {
            return;
        }
        if (historyDrawTimes == 0) {
            TreasureCallRow callRow = showCallRow(1);
            if (callRow != null) {
                freeTimes = callRow.freeLimit;
            }
        }

    }

    public void clear() {
        freeTimes = 0;
        historyDrawTimes = 0;
        diaTimes = 0;
        exchange.clear();
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        if (!enable() || showCallRow(1) == null) {
            return;
        }
        this.diaTimes = 0;
        this.freeTimes = showCallRow(1).freeLimit;
        exchange.onDaySpan(silence);
        noticeUpdate();
    }

    /*@Override
    public void onWeekSpan(boolean silence) {
        super.onWeekSpan(silence);
        if (!enable()) {
            return;
        }
        exchange.onWeekSpan(silence);
    }*/

    public void noticeUpdate() {
        role.sendNow(new TreasureInfoResp(this));
    }

    public GameResult<TreasureActivity> draw(int type) {
        GameResult<TreasureActivity> r = new GameResult<>();
        TreasureCallRow callRow = showCallRow(type);
        if (callRow == null) {
            return r.fail("配置不存在");
        }
        MixRes cost = new MixRes(callRow.cost);
        boolean isFree = false;
        boolean isDia = false;
        //免费抽
        if (type == 1 && freeTimes > 0) {
            isFree = true;
        } else {
            //道具消耗检测
            if (StringUtils.isBlank(callRow.cost)) {
                return r.fail("消耗未配置");
            }
            GameResult<MixResItem> consume = cost.consumeCheck(role);
            if (!consume.ok()) {
                //钻石消耗
                if (callRow.diaLimit > 0) {
                    if (diaTimes + callRow.count > callRow.diaLimit ) {
                        return r.fail("钻石召唤次数不足");
                    }
                    cost = new MixRes(callRow.costDia);
                    GameResult<MixResItem> consumeDia = cost.consumeCheck(role);
                    if (!consumeDia.ok()) {
                        return r.fail(consumeDia);
                    }
                    isDia = true;
                } else {
                    return r.fail(consume);
                }
            }
        }
        r = drawItems(callRow);
        if (r.ok()) {
            if (isFree) {
                freeTimes --;
            } else {
                if (isDia) {
                    diaTimes += callRow.count;
                }
                cost.consume(role);
            }
            noticeUpdate();
        }
        return r;
    }

    private TreasureCallRow showCallRow(int type) {
        TreasureCallRow row = role.getGame().table.treasure.call.showCallType(configTid(), type);
        return row;
    }

    private TreasureOutputRow showOutputRow(int groupId) {
        TreasureOutputRow row = role.getGame().table.treasure.output.showOutputRow(groupId);
        return row;
    }

    private TreasureBaseRow showBaseRow(int callTimes) {
        TreasureBaseRow row = role.getGame().table.treasure.base.showBaseRow(configTid(), callTimes);
        return row;
    }

    private GameResult<TreasureActivity> drawItems(TreasureCallRow callRow) {
        GameResult<TreasureActivity> r = new GameResult<>();


        int rareNum = 0;
        List<MixRes> rewardShow = new ArrayList<>();
        List<MixRes> rewardAddShow = new ArrayList<>();
        MixRes rewards = new MixRes();
        List<TreasureCallPoolRow> rows = new ArrayList<>();
        long startMs = System.currentTimeMillis();
        while (rows.size() < callRow.count) {
            if (System.currentTimeMillis() - startMs > 5000L) {
                break;
            }
            TreasureBaseRow baseRow = showBaseRow(historyDrawTimes + 1);
            if (baseRow == null) {
                return r.fail("基础配置错误");
            }
            TreasureOutputRow outputRow = showOutputRow(baseRow.groupId);
            if (outputRow == null) {
                return r.fail("暴击配置错误");
            }
            //道具
            MixResItem rewardItem = MixResItem.parse(outputRow.reward);

            TreasureCallPoolRow row = role.getGame().table.treasure.pool.randomPool(baseRow.groupId);
            if (!row.rare || rareNum < callRow.rareLimit) {

                historyDrawTimes ++;
                rows.add(row);
                // 暴击产出
                MixResItem rewardCheck = MixResItem.parse(row.reward);
                boolean ifAdd = false;
                if (rewardCheck.tid == rewardItem.tid) {
                    int numAdd = (int) Math.ceil(rewardCheck.num * outputRow.rate);
                    if (XT.chance((int) (outputRow.probability*10000))) {
                        numAdd += rewardCheck.num;
                        MixResItem rewardAdd = new MixResItem(rewardItem.type, rewardItem.tid, numAdd);
                        rewardAddShow.add(new MixRes().addItem(rewardAdd));
                        rewards.addList(new MixRes().addItem(rewardAdd));
                        ifAdd = true;
                        //稀有加暴击
                        if (row.rare) {
                            rareNum ++;
                            if (callRow.lampAddId != 0) {
                                List<ChatContentParam> params = new ArrayList<>();
                                params.add(ChatContentParam.c(role.getBase().name));
                                params.add(ChatContentParam.c(ChatContentParam.TYPE_MIX_RES, new MixRes().addItem(rewardAdd)));
                                role.getGame().notice.lampOnline(role, callRow.lampAddId, params);
                            }
                        }
                    }
                }
                if (!ifAdd) {
                    rewardShow.add(new MixRes(row.reward));
                    rewards.addList(new MixRes(row.reward));
                    //稀有
                    if (row.rare) {
                        rareNum ++;
                        if (callRow.lampId != 0) {
                            List<ChatContentParam> params = new ArrayList<>();
                            params.add(ChatContentParam.c(role.getBase().name));
                            params.add(ChatContentParam.c(ChatContentParam.TYPE_MIX_RES, new MixRes(row.reward)));
                            role.getGame().notice.lampOnline(role, callRow.lampId, params);
                        }
                    }
                }

            }
        }
        rewardShow.add(new MixRes(callRow.extraRwd));
        rewards.addList(new MixRes(callRow.extraRwd));
        EcResult<?> exe = new MixResAdder().setRes(rewards)
                .setOperation(GDOperation.TREASURE)
                .setDialogReward(false)
                .setSendMailWhenFull(true)
                .exe(role);
        TreasureDrawResp resp = new TreasureDrawResp(rewardShow, rewardAddShow);
        resp.sendNow(role);

        return r;
    }

    public GameResult<TreasureActivity> exchange(int tid, int num) {
        GameResult<TreasureActivity> r = new GameResult<>();
        if (num <= 0) {
            return r.fail("数量错误");
        }
        r = exchange.exchangeItem(tid, num);
        if (r.ok()) {
            noticeUpdate();
        }
        return r;
    }
}
